package main

import (
	"os"
	"fmt"
	"json"
)

type Config map[string]interface{}

const (
	CFGK_PORT        = "port"
	CFGK_ROOT_FOLDER = "rootFolder"
	CFGK_FS_ONLY     = "fsonly"
	CFGK_HTTPS       = "use-https"
	CFGK_CERT_FILE   = "certFile"
	CFGK_KEY_FILE    = "keyFile"
)

// Load the config file from the server
func loadConfig(file string) (cfg Config, err os.Error) {
	cfg = make(Config)
	fi, err := os.Stat(file)
	if err != nil {
		return
	}

	if !fi.IsRegular() {
		err = os.NewError(fmt.Sprintf("File %v is not regular file", file))
		return
	}

	f, err := os.Open(file)
	if err != nil {
		return
	}
	defer f.Close()

	dec := json.NewDecoder(f)
	err = dec.Decode(&cfg)

	if err != nil {
		return
	}
	return
}

// Read a string from the config
func (c Config) GetString(key string) (ret string, err os.Error) {
	val, ok := c[key]
	if ok {
		switch val.(type) {
		case string:
			ret = val.(string)
		default:
			err = os.NewError(fmt.Sprintf("Unable to handle type for key %v. Value is %v", key, val))
		}
	} else {
		err = os.NewError(fmt.Sprintf("The key %v isn't in the config.", key))
	}
	return
}

func (c Config) GetBool(key string) (ret bool, err os.Error) {
	v, err := c.GetString(key)
	if err != nil {
		return false, err
	} else {
		return v == "y" || v == "Y" || v == "1", nil
	}
	return
}

// Read a subconfig from the config
func (c Config) SubCfg(key string) (ret Config, err os.Error) {
	val, ok := c[key]
	if ok {
		switch val.(type) {
		case map[string]interface{}:
			ret = Config(val.(map[string]interface{}))
			break
		default:
			err = os.NewError(fmt.Sprintf("Unable to handle type for key %v. Value is %v", key, val))
			break
		}
	} else {
		err = os.NewError(fmt.Sprintf("The key %v isn't in the config.", key))
	}
	return
}

// Put a value on the config if the key isn't already there
func (c Config) PutIfNone(key string, value interface{}) {
	_, ok := c[key]
	if !ok {
		// store the value on the config
		switch value.(type) {
		case bool:
			if value.(bool) {
				c[key] = "y"
			} else {
				c[key] = "n"
			}
			break
		default:
			c[key] = value
			break
		}
	}
}

// Return a string representation from the
// wrapper map
func (c Config) String() (ret string) {
	ret = fmt.Sprintf("Config{%v}", map[string]interface{}(c))
	return
}
